// Protocol.hpp
#pragma once
#include <iostream>
#include <string>

// 制定协议，并提供序列化和反序列化的功能

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

// 添加报头形成整个报文，package = "len"\n"content"\n
std::string Encode(std::string &content)
{
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

// 去掉报头提取有效载荷
bool Decode(std::string &package, std::string *content)
{
    size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
    size_t len = std::stoi(package.substr(0, pos)); // 有效载荷的长度

    // package.size() == len_str + content_str + 2
    size_t total_len = pos + len + 2;
    if (package.size() < total_len)
        return false;

    *content = package.substr(pos + 1, len);
    package.erase(0, total_len);  // 移除报文
    return true;
}

// 请求
class Request
{
public:
    Request(int data1, int data2, char oper)
        : x(data1), y(data2), op(oper)
    {
    }
    Request() {}

public:
    // 序列化
    bool Serialize(std::string *out)
    {
        // 构建报文的有效载荷
        // struct => string, "x op y"
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
        return true;
    }
    // 反序列化
    bool Deserialize(const std::string &in)
    {
        // in = "x op y"
        size_t pos1 = in.find(blank_space_sep);
        if (pos1 == std::string::npos)
            return false;
        std::string part_x = in.substr(0, pos1);

        size_t pos2 = in.rfind(blank_space_sep); // 逆向查找
        if (pos2 == std::string::npos)
            return false;
        std::string part_y = in.substr(pos2 + 1);

        if (pos1 + 2 != pos2)
            return false;
        op = in[pos1 + 1];

        x = std::stoi(part_x);
        y = std::stoi(part_y);
        return true;
    }
    void DebugPrint()
    {
        std::cout << "新请求构建完成：" << x << op << y << "=?" << std::endl;
    }
public:
    int x;
    int y;
    char op; // + - * / %
};

// 应答
class Response
{
public:
    Response(int res, int c)
        : result(res), code(c)
    {
    }
    Response() {}

public:
    bool Serialize(std::string *out)
    {
        // 构建报文的有效载荷
        // struct => string, "result code"
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
        return true;
    }
    bool Deserialize(const std::string &in)
    {
        // in = "result code"
        size_t pos = in.find(blank_space_sep);
        if (pos == std::string::npos)
            return false;
        std::string part_result = in.substr(0, pos);
        std::string part_code = in.substr(pos + 1);

        result = std::stoi(part_result);
        code = std::stoi(part_code);

        return true;
    }
    void DebugPrint()
    {
        std::cout << "结果相应完成, result: " << result << ", code: " << code << std::endl;
    }
public:
    int result;
    int code; // 0，可信；!0，不可信，具体值表明错误原因
};